import axios from 'axios'
import Qs from 'qs'
import { resPost, getRes } from '@/common/requestEncy' // web 请求、响应加解密
// import { requestEncry, responseEncry } from '@/common/requestNte'// 原生 请求、响应加解密
// import nativeLogin from '@/common/nativeLogin'
import { getToken } from '@/common/auth'
import store from '../store'
import wx from './wxapi'
const CancelToken = axios.CancelToken
// 防止重复请求
const removePending = (config) => {
  for (const k in store.state['axiosPromiseCancel']) {
    if (store.state['axiosPromiseCancel'][k].u === config.url + '&' + config.method + '&params=' + (config.method === 'get' ? JSON.stringify(config.params) : JSON.stringify(config.data))) { // 当前请求在数组中存在时执行函数体
      store.state['axiosPromiseCancel'][k].f() // 执行取消操作
      store.state['axiosPromiseCancel'].splice(k, 1) // 把这条记录从数组中移除
    }
  }
}
const getQueryObject = function(url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}
const service = axios.create({
  // 自定义的请求头
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cache-Control': 'no-cache'
  },
  // 超时设置
  timeout: 1000000,
  // 跨域是否带Token
  withCredentials: true,
  // // XSRF 设置
  xsrfCookiesName: 'XSRF-TOKEN',
  xsrfHeaderName: 'X-XSRF-TOKEN',
  transformRequest: [(data) => {
    data = Qs.stringify(data)
    return data
  }],
  transformResponse: [(data) => {
    return data
  }]
})

/**
 * 传参序列化
 */
service.interceptors.request.use(
  config => {
    if (getToken()) {
      config.headers['ttsxyhcs'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
      config.headers['ttsxauthtoken'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
    }
    if (wx.isweixin()) {
      config.headers['ClientType'] = 'weixin'
    } else if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
      config.headers['ClientType'] = 'h5'
    } else if (/(Android)/i.test(navigator.userAgent)) {
      config.headers['ClientType'] = 'h5'
    } else {
      config.headers['ClientType'] = 'pc'
    }
    config.headers['ttsxbid'] = 1 // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
    if (config.method === 'get') {
      const params = config.params
      for (const key in params) {
        if (params[key] === undefined) {
          params[key] = ''
        }
      }
      config.params = params
      const signParams = { ...config.params || {}, ...getQueryObject(config.url) }
      config = resPost(config, signParams) // web端处理
      // config = requestEncry(config, config.params || null) // 原生处理
    } else if (config.method === 'post') {
      const params = config.data
      for (const key in params) {
        if (params[key] === undefined) {
          params[key] = ''
        }
      }
      config.data = params
      const signParams = { ...config.data || {}, ...getQueryObject(config.url) }
      config = resPost(config, signParams) // web端处理
      // config = requestEncry(config, config.data || null) // 原生处理
    }
    // ------------------------------------------------------------------------------------
    // 这个是 取消重点
    removePending(config)
    config.cancelToken = new CancelToken((cancel) => {
      store.state['axiosPromiseCancel'].push({
        u: config.url + '&' + config.method + '&params=' + (config.method === 'get' ? JSON.stringify(config.params) : JSON.stringify(config.data)),
        f: cancel
      })
    })
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
/**
 * 返回状态判断
 */
service.interceptors.response.use(
  response => {
    // ------------------------------------------------------------------------------------------
    removePending(response.config) // 在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
    // -------------------------------------------------------------------------------------------
    /**
     * 原生处理返回值仿篡改
     */
    // if (!responseEncry(response)) {
    //   window.$Vue.$dialog.confirm({
    //     title: '提示',
    //     mes: '返回数据被篡改',
    //     opts: [{
    //       txt: '确定',
    //       color: true
    //     }]
    //   })
    //   return false
    // }
    /**
     * web端处理返回值仿篡改
     */
    if (!getRes(response)) {
      window.$Vue.$dialog.confirm({
        title: '提示',
        mes: '返回数据被篡改',
        opts: [{
          txt: '确定',
          color: true
        }]
      })
      return false
    }
    if (response.data) {
      response.data = JSON.parse(response.data)
    }
    const res = response.data
    if (res.code && res.code !== '200' && res.code !== '1') {
      if (res.code === '401' || res.code === 401) {
        window.$Vue.$store.dispatch('setLoginState', false)
        if (window.$Vue.$route.name === 'center' || window.$Vue.$route.name === 'index') {
          return
        }
        localStorage.setItem('isToLogin', 1)
        window.$Vue.$router.replace('/login')
      } else if (res.code === '404' || res.code === 404) {
        window.$Vue.$router.replace('/404')
      } else if (res.code === '9999' || res.code === 9999) {
        return res
      }else if (res.code === '8888' || res.code === 8888) {
        return res
      } else {
        window.$Vue.$dialog.confirm({
          title: '提示',
          mes: res.msg || '网络异常！',
          opts: [{
            txt: '确定',
            color: true
          }]
        })
      }
    } else {
      if (!store.state.isLogin) {
        window.$Vue.$store.dispatch('setLoginState', true)
      }
      return res
    }
  },
  error => {
    if (axios.isCancel(error)) {
      // 为了终结promise链 就是实际请求 不会走到.catch(rej=>{});这样就不会触发错误提示之类了。
      return new Promise(() => {
      })
    } else {
      return Promise.reject(error)
    }
  }
)

export default service
